package models

import (
	"awesome-devops/applications/rpc/client"
	"awesome-devops/applications/rpc/define"
	"awesome-devops/applications/tools"
	"context"
	"gitee.com/jjawesomejj/awesome-util/helper/commonhelper"
	"gorm.io/gorm"
	"time"
)

type Runner struct {
	BaseModel
	ID            uint      `json:"id"`
	Ip            string    `json:"ip"`
	RpcPort       int       `json:"rpc_port"`
	WsPort        int       `json:"ws_port"`
	Name          string    `json:"name"`
	Description   string    `json:"description"`
	Labels        string    `json:"labels"`
	ExtensionJson string    `json:"extension_json"`
	UniqueId      string    `json:"unique_id"`
	CreateTime    time.Time `json:"create_time"`
	UpdateTime    time.Time `json:"update_time"`
	DeleteTime    int       `json:"delete_time"`
}

func (baseModel *Runner) BeforeCreate(tx *gorm.DB) (err error) {
	baseModel.CreateTime = time.Now()
	baseModel.UpdateTime = time.Now()
	return tx.Error
}

func (baseModel *Runner) BeforeSave(tx *gorm.DB) (err error) {
	baseModel.CreateTime = time.Now()
	baseModel.UpdateTime = time.Now()
	return tx.Error
}

func (baseModel *Runner) GetRunnerLabels() []int {
	labelIds := baseModel.Labels
	var data []int
	err := commonhelper.JsonDecodeWithType(labelIds, &data)
	if err != nil {
		return make([]int, 0)
	} else {
		return data
	}

}

//CheckLabelIsMatch 检查标签是否匹配
func (baseModel *Runner) CheckLabelIsMatch(labels []int) bool {
	//节点与项目均未设置标签 认为可以在此节点运行
	runnerLabels := baseModel.GetRunnerLabels()
	if len(labels) == 0 && len(runnerLabels) == 0 {
		return true
	} else {
		for _, labelId := range labels {
			for _, runnerLabel := range runnerLabels {
				if labelId == runnerLabel {
					return true
				}
			}
		}
	}
	return false
}

func (baseModel *Runner) TableName() string {
	return "ops_runner"
}

func (baseModel *Runner) GetNodeRunnerResource() (NodeInfo, error) {
	grpcClient := client.GetRpcClient(baseModel.Ip, baseModel.RpcPort)
	service, err := grpcClient.GetNodeService()
	if err != nil {
		return NodeInfo{}, err
	}
	response, err := service.GetNodeResource(context.Background(), &define.NodeInfoRequest{})
	if err != nil {
		tools.GetLogger().Error(err.Error())
		return NodeInfo{}, err
	}
	nodeInfo := NodeInfo{
		Cpu:           response.Cpu,
		CpuSurplus:    response.CpuSurplus,
		MemoryTotal:   response.MemoryTotal,
		SurplusMemory: response.SurplusMemory,
		CpuUsage:      response.Cpu - response.CpuSurplus,
		MemoryUsage:   response.MemoryTotal - response.SurplusMemory,
	}
	return nodeInfo, nil
}

type NodeInfo struct {
	Cpu           int32 `json:"cpu"`
	CpuSurplus    int32 `json:"cpu_surplus"`
	CpuUsage      int32 `json:"cpu_usage"`
	MemoryTotal   int64 `json:"memory_total"`
	SurplusMemory int64 `json:"surplus_memory"`
	MemoryUsage   int64 `json:"memory_usage"`
}
